﻿using System;
using System.Text;
using System.Windows.Forms;

namespace ZYB_S007_串口调试器
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            set_display_right();  //居右显示
        }
        Config_Json_Rs232 config = Config_Json_Rs232.ReadAll();
        private void Form1_Load(object sender, EventArgs e)
        {
            SOFT_VER.Text = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();

            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo("logs/");
            if (di.Exists == false) di.Create();

            //foreach (string com in System.IO.Ports.SerialPort.GetPortNames()) //自动获取串行口名称
            //{
            //    cbb_serial_portname.Items.Add(com);
            //}
            //cbb_serial_portname.SelectedIndex = 0;
            try
            {
                using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("select * from Win32_PnPEntity"))
                {
                    var hardInfos = searcher.Get();
                    int index = 1;
                    foreach (var hardInfo in hardInfos)
                    {
                        if (hardInfo.Properties["Name"].Value != null && hardInfo.Properties["Name"].Value.ToString().Contains("(COM"))
                        {
                            String strComName = hardInfo.Properties["Name"].Value.ToString();
                           cbb_serial_portname.Items.Add(index + ":" + strComName);//打印串口设备名称及串口号
                            index += 1;
                        }
                    }
                }
                Console.ReadKey();
            }
            catch
            {
                
            }
            restore_config();

        }

        private void restore_config()
        {
            cbb_serial_portname.Text = config.串口号;
            cb_baudrate.Text = config.波特率;
            cb_databits.Text = config.数据位;
            cb_parity.Text = config.奇偶校验;
            cb_16进制.Checked = config.使用16进制;

            cb_stopbits.Text = config.停止位;
            cb_显示时间.Checked = config.显示时间;
            cb_加回车换行符.Checked = config.加回车换行符;

            tb生产厂商.Text = config.生产厂商;
            tb官网.Text = config.官网;
            tb名称.Text = config.名称;
            tb型号.Text = config.型号;

            cb_常用指令加回车.Checked = config.常用指令加回车;
            cb_常用指令16进制.Checked = config.常用指令16进制;
            tb_指令1.Text = config.指令1;
            tb_指令2.Text = config.指令2;
            tb_指令3.Text = config.指令3;
            tb_指令4.Text = config.指令4;
            tb_指令5.Text = config.指令5;
            tb_指令6.Text = config.指令6;
            tb_指令7.Text = config.指令7;
            tb_指令8.Text = config.指令8;

            tb_用途1.Text = config.用途1;
            tb_用途2.Text = config.用途2;
            tb_用途3.Text = config.用途3;
            tb_用途4.Text = config.用途4;
            tb_用途5.Text = config.用途5;
            tb_用途6.Text = config.用途6;
            tb_用途7.Text = config.用途7;
            tb_用途8.Text = config.用途8;

            switch (config.接口)
            {
                case "待确认":
                    rb接口待确认.Checked = true;
                    break;
                case "公头":
                    rb接口公头.Checked = true;
                    break;
                case "母头":
                    rb接口母头.Checked = true;
                    break;
                case "USB":
                    rb接口USB.Checked = true;
                    break;
                default:
                    rb接口待确认.Checked = true;
                    break;

            }

            if (config.连接线 == "待确认") rb连接线待确认.Checked=true;
            if (config.连接线 == "直通") rb连接线直通.Checked = true;
            if (config.连接线 == "交叉") rb连接线交叉.Checked = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            serial_open();
        }

        bool serial_open()
        {
            if (serialPort1.IsOpen) serialPort1.Close();

            if (cbb_serial_portname.Text.Contains("("))
            {
                serialPort1.PortName = cbb_serial_portname.Text.Substring(cbb_serial_portname.Text.IndexOf("(") + 1, cbb_serial_portname.Text.IndexOf(")") - cbb_serial_portname.Text.IndexOf("(") - 1);
            }
            else
            {
                serialPort1.PortName = cbb_serial_portname.Text;
            }

            serialPort1.BaudRate = Convert.ToInt32(cb_baudrate.Text);
            serialPort1.DataBits = Convert.ToInt16(cb_databits.Text);

            switch (cb_stopbits.Text)
            {
                case "1":
                    this.serialPort1.StopBits = System.IO.Ports.StopBits.One;
                    break;
                case "1.5":
                    this.serialPort1.StopBits = System.IO.Ports.StopBits.OnePointFive;
                    break;
                case "2":
                    this.serialPort1.StopBits = System.IO.Ports.StopBits.Two;
                    break;
                default:
                    break;
            }
            switch (cb_parity.Text)
            {
                case "None":
                    serialPort1.Parity = System.IO.Ports.Parity.None;
                    break;
                case "Odd":
                    serialPort1.Parity = System.IO.Ports.Parity.Odd;
                    break;
                case "Even":
                    serialPort1.Parity = System.IO.Ports.Parity.Even;
                    break;
                default:
                    break;
            }
            addmemo("打开端口：" + serialPort1.PortName+","+cb_baudrate.Text+","+cb_databits.Text+","+cb_stopbits.Text+","+cb_parity.Text);
            try
            {
                serialPort1.Open();
                lb_串口状态.Text = "已打开";
                return true;
            }
            catch (Exception ex)
            {
                addmemo(ex.Message);
                return false;
            }

        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            System.Threading.Thread.Sleep(200);
            //this.Invoke(new Action(() =>
           // {
                if (cb_16进制.Checked)
                {
                    Byte[] receivedData = new Byte[serialPort1.BytesToRead]; //创建接收字节数组 
                    serialPort1.Read(receivedData, 0, receivedData.Length);  //读取数据 
                    addmemo("收："+  ByteToHex(receivedData));
                }
                else
                {
                    addmemo("收："+ serialPort1.ReadExisting());
                }
          //  }),null);
        }
        private string ByteToHex(byte[] comByte)
        {
            StringBuilder builder = new StringBuilder(comByte.Length * 3);
            foreach (byte data in comByte)
                builder.Append(Convert.ToString(data, 16).PadLeft(2, '0'));
            return builder.ToString().ToUpper();
        }

        private void addmemo(string memo)
        {
            this.Invoke(new Action(() =>
            {
                if (cb_显示时间.Checked)
                    tb_received.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + memo + "\r\n");
                else
                    tb_received.AppendText(memo + "\r\n");
                tb_received.ScrollToCaret();
            }), null);
            try
            {
                using (System.IO.StreamWriter writer = new System.IO.StreamWriter("logs/"+DateTime.Now.ToString("yyyy-MM-dd")+".txt", true))
                {
                    writer.Write(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + memo + "\r\n");
                    writer.Close();
                }
            }
            catch { }

        }

        private void btn_save_Click(object sender, EventArgs e)
        {
            config.串口号 = cbb_serial_portname.Text;
            config.波特率 = cb_baudrate.Text;
            config.数据位 = cb_databits.Text;
            config.奇偶校验 = cb_parity.Text;
            config.使用16进制 = cb_16进制.Checked;

            config.停止位 = cb_stopbits.Text;
            config.显示时间 = cb_显示时间.Checked;
            config.加回车换行符 = cb_加回车换行符.Checked;

            Config_Json_Rs232.save(config);
        }

        private void btn发送_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_16进制.Checked, tb发送字符.Text, cb_加回车换行符.Checked);
        }

        void serial_send_command(bool 使用16进制,string command,bool 加回车换行符)
        {
            if (lb_串口状态.Text != "已打开")
            {
                if (serial_open() == false) return;
            }

            if (使用16进制)
            {
                byte[] t = HexToByte(command);
                serialPort1.Write(t, 0, t.Length);
                addmemo("发：" + command);
            }
            else
            {
                if (加回车换行符)
                {
                    serialPort1.Write(command + "\r\n");
                    addmemo("发：" + command + "\r\n");
                }
                else
                {
                    serialPort1.Write(command);
                    addmemo("发：" + command);
                }
            }
        }



        private byte[] HexToByte(string msg)
        {
            msg = msg.Replace(" ", "");
            byte[] comBuffer = new byte[msg.Length / 2];
            for (int i = 0; i < msg.Length; i += 2)
                comBuffer[i / 2] = (byte)Convert.ToByte(msg.Substring(i, 2), 16);
            return comBuffer;
        }

        private void button3_Click(object sender, EventArgs e) //默认值
        {
            cb_baudrate.Text = "9600";
            cb_databits.Text = "8";
            cb_stopbits.Text = "1";
            cb_parity.Text = "None";
        }

        private void cb_16进制_CheckedChanged(object sender, EventArgs e)
        {
            config.使用16进制 = cb_16进制.Checked;
            Config_Json_Rs232.save(config);
        }

        private void cb加回车换行符_CheckedChanged(object sender, EventArgs e)
        {
            config.加回车换行符 = cb_加回车换行符.Checked;
            Config_Json_Rs232.save(config);
        }

        private void cb_显示时间_CheckedChanged(object sender, EventArgs e)
        {
            config.显示时间 = cb_显示时间.Checked;
            Config_Json_Rs232.save(config);
        }

        private void btn_保存仪表信息_Click(object sender, EventArgs e)
        {
            config.生产厂商 = tb生产厂商.Text;
            config.官网 = tb官网.Text;
            config.名称 = tb名称.Text;
            config.型号 = tb型号.Text;

            if (rb接口待确认.Checked) config.接口 = "待确认";
            if (rb接口公头.Checked) config.接口 = "公头";
            if (rb接口母头.Checked) config.接口 = "母头";
            if (rb接口USB.Checked) config.接口 = "USB";

            if (rb连接线待确认.Checked) config.连接线 = "待确认";
            if (rb连接线直通.Checked) config.连接线 = "直通";
            if (rb连接线交叉.Checked) config.连接线 = "交叉";
            addmemo("保存仪表信息："+ config.生产厂商+" " +config.官网 + " " + config.名称 + " " + config.型号 + " " + config.接口 + " " + config.连接线);
            Config_Json_Rs232.save(config);
            addmemo("保存成功！");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            config.常用指令加回车 = cb_常用指令加回车.Checked;
            config.常用指令16进制 = cb_常用指令16进制.Checked;
            config.指令1 = tb_指令1.Text;
            config.指令2 = tb_指令2.Text;
            config.指令3 = tb_指令3.Text;
            config.指令4 = tb_指令4.Text;
            config.指令5 = tb_指令5.Text;
            config.指令6 = tb_指令6.Text;
            config.指令7 = tb_指令7.Text;
            config.指令8 = tb_指令8.Text;
            config.用途1 = tb_用途1.Text;
            config.用途2 = tb_用途2.Text;
            config.用途3 = tb_用途3.Text;
            config.用途4 = tb_用途4.Text;
            config.用途5 = tb_用途5.Text;
            config.用途6 = tb_用途6.Text;
            config.用途7 = tb_用途7.Text;
            config.用途8 = tb_用途8.Text;
            addmemo("保存指令：\r\n"
                +"指令1："+config.指令1+" 用途："+config.用途1+"\r\n"
                + "指令2：" + config.指令2 + " 用途：" + config.用途2 + "\r\n"
                + "指令3：" + config.指令3 + " 用途：" + config.用途3 + "\r\n"
                + "指令4：" + config.指令4 + " 用途：" + config.用途4 + "\r\n"
                + "指令5：" + config.指令5 + " 用途：" + config.用途5 + "\r\n"
                + "指令6：" + config.指令6 + " 用途：" + config.用途6 + "\r\n"
                + "指令7：" + config.指令7 + " 用途：" + config.用途7 + "\r\n"
                + "指令1：" + config.指令8 + " 用途：" + config.用途8 + "\r\n"
                );
            Config_Json_Rs232.save(config);
            addmemo("保存成功！");
        }

        private void btn_发送1_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令1.Text, cb_常用指令加回车.Checked);
            addmemo("用途:"+tb_用途1.Text);
        }

        private void btn_发送2_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令2.Text, cb_常用指令加回车.Checked);
            addmemo("用途:" + tb_用途2.Text);
        }

        private void btn_发送3_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令3.Text, cb_常用指令加回车.Checked);
             addmemo("用途:" + tb_用途3.Text);
        }

        private void btn_发送4_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令4.Text, cb_常用指令加回车.Checked);
            addmemo("用途:" + tb_用途4.Text);
        }

        private void btn_发送5_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令5.Text, cb_常用指令加回车.Checked);
            addmemo("用途:" + tb_用途5.Text);
        }

        private void btn_发送6_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令6.Text, cb_常用指令加回车.Checked);
            addmemo("用途:" + tb_用途6.Text);
        }

        private void btn_发送7_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令7.Text, cb_常用指令加回车.Checked);
            addmemo("用途:" + tb_用途7.Text);
        }

        private void btn_发送8_Click(object sender, EventArgs e)
        {
            serial_send_command(cb_常用指令16进制.Checked, tb_指令8.Text, cb_常用指令加回车.Checked);
            addmemo("用途:" + tb_用途8.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) serialPort1.Close();
            lb_串口状态.Text = "已关闭";
            addmemo(serialPort1.PortName + "已关闭");
        }

        private void button5_Click(object sender, EventArgs e)
        {
            config.串口号 = cbb_serial_portname.Text;
            Config_Json_Rs232.save(config);
            MessageBox.Show("串口号已保存");
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(tb官网.Text);
        }

    
        private void 导出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string path = System.IO.Directory.GetCurrentDirectory()+"/导出配置文件/";  //不能使用 "d:/蓄电池_测试记录/" 否则将不能初始化定位到这个目录
            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(path);
            if (di.Exists == false) di.Create();

            SaveFileDialog fileDialog = new SaveFileDialog();
            fileDialog.Filter = "Json|*.json";

            fileDialog.InitialDirectory = path;
            fileDialog.FileName =  "串口配置_" + tb名称.Text+tb型号.Text+".json";

            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                Config_Json_Rs232.save( config, fileDialog.FileName);
                addmemo("导出配置成功："+fileDialog.FileName);
            }
            fileDialog.Dispose();
        }

        private void 导入ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = System.IO.Directory.GetCurrentDirectory() + "/导出配置文件/";
            openFileDialog.Filter = "Json|*.json";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string tt = System.IO.File.ReadAllText(openFileDialog.FileName);
                try
                {
                    addmemo("导入配置："+openFileDialog.FileName);
                    config = Newtonsoft.Json.JsonConvert.DeserializeObject<Config_Json_Rs232>(tt);
                    restore_config();
                    addmemo("导入配置成功");
                }
                catch (Exception ex)
                {
                    addmemo("导入出错：" +ex.Message);
                }
                
            }
        }

        private void 保存当前配置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Config_Json_Rs232.save(config);
            addmemo("保存当前配置成功！");
        }

        private void tCP调试ToolStripMenuItem_Click(object sender, EventArgs e)
        {
           
        }
        void set_display_right()
        {
            //500,900
            int SH = Screen.PrimaryScreen.Bounds.Height; //1080
            int SW = Screen.PrimaryScreen.Bounds.Width; //1920
            this.Location = new System.Drawing.Point(SW - this.Width-50, SH / 2 - this.Height / 2);
        }

        private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 a = new AboutBox1();
            a.ShowDialog();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Title = "保存当前界面为图片";
            sfd.FileName = "串口通讯" + "_" +tb名称.Text+tb型号.Text+"_"+ DateTime.Now.ToString("yyyyMMdd_HHmmss");
            //默认保存为启动程序目录
            //sfd.InitialDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            //保存我和图片目录
            sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);

            sfd.Filter = "图片文件（*.png）|*.png";
            //设置默认文件类型显示顺序
            sfd.FilterIndex = 1;

            //保存对话框是否记忆上次打开的目录
            sfd.RestoreDirectory = true;

            //点了保存按钮进入
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                Capture_Window_Pic.caputure_pic(sfd.FileName);
                addmemo("截图保存成功：" + sfd.FileName+",请按提示选择是否要立即查看图片");
                if (MessageBox.Show("图片已保存，是否需要立即查看？", "提示", MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start(sfd.FileName);
                }
            }
           
        }

        private void modbus调试ToolStripMenuItem_Click(object sender, EventArgs e)
        {
          
        }

        private void modbusRtuToolStripMenuItem_Click(object sender, EventArgs e)
        {
           
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void Ping_Click(object sender, EventArgs e)
        {
           
        }

       

        private void aPIToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}
